package com.xbts.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xbts.common.config.XbtsConfig;
import com.xbts.common.constant.Constants;
import com.xbts.common.constant.UserConstants;
import com.xbts.common.core.domain.model.LoginUser;
import com.xbts.common.exception.ServiceException;
import com.xbts.common.utils.DateUtils;
import com.xbts.common.utils.SecurityUtils;
import com.xbts.common.utils.SnowFlakeUtil;
import com.xbts.common.utils.StringUtils;
import com.xbts.common.utils.file.FileUtils;
import com.xbts.common.utils.list.ListUtils;
import com.xbts.system.domain.CnWorkOrder;
import com.xbts.system.domain.CnWorkOrderDetail;
import com.xbts.system.enums.WorkOrderStatusEnum;
import com.xbts.system.mapper.CnWorkOrderMapper;
import com.xbts.system.service.ICnWorkOrderDetailService;
import com.xbts.system.service.ICnWorkOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 工单Service业务层处理
 *
 * @author xbts
 * @date 2023-08-28
 */
@Service
public class CnWorkOrderServiceImpl extends ServiceImpl<CnWorkOrderMapper, CnWorkOrder> implements ICnWorkOrderService {

    @Autowired
    private ICnWorkOrderDetailService cnWorkOrderDetailService;

    /**
     * 查询工单列表
     *
     * @param cnWorkOrder 工单
     * @return 工单
     */
    @Override
    public List<CnWorkOrder> selectCnWorkOrderList(CnWorkOrder cnWorkOrder) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        cnWorkOrder.setUserId(loginUser.getUserId());

        QueryWrapper<CnWorkOrder> queryWrapper = cnWorkOrder.queryWrapper();
        // 用userType 判断是否是管理人员
        if (!loginUser.getUser().getUserType().equals(UserConstants.USER_TYPE_MANAGER)) {
            queryWrapper.eq("cwo.create_by", SecurityUtils.getUserId().toString());
        }
        queryWrapper.eq(StringUtils.isNotNull(cnWorkOrder.getStatus()),"cwo.status", cnWorkOrder.getStatus() );
        queryWrapper.like(StringUtils.isNotBlank(cnWorkOrder.getUserName()), "su.user_name", cnWorkOrder.getUserName());
        queryWrapper.orderByDesc("cwo.create_time");
        List<CnWorkOrder> list = baseMapper.selectCnWorkOrderList(queryWrapper);

        QueryWrapper<CnWorkOrderDetail> childrenItemWrapper = new QueryWrapper<CnWorkOrderDetail>()
                .eq("read_status", false)
                .ne("create_by", loginUser.getUserId()); // 排除自己新增的留言

        Map<String, Object> map = ListUtils.getChildrenItem(list, "orderNum", cnWorkOrderDetailService, childrenItemWrapper);
        Map<String, Integer> mm = new HashMap<>(); // 用于存放订单的未读消息数
        if (map != null && map.size() > 0) {
            for (Map.Entry<String, Object> stringObjectEntry : map.entrySet()) {
                mm.put(stringObjectEntry.getKey(), ((List<?>) stringObjectEntry.getValue()).size());
            }
            list.forEach(item -> item.setUnReadNum(mm.getOrDefault(item.getOrderNum(), 0)));
        }
        return list;
    }

    /**
     * 查询工单
     *
     * @param orderNum 工单主键
     * @return 工单
     */
    @Override
    public CnWorkOrder selectCnWorkOrderByOrderNum(String orderNum) {
        return getById(orderNum);
    }

    /**
     * 新增工单
     *
     * @param cnWorkOrder 工单
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean insertCnWorkOrder(CnWorkOrder cnWorkOrder) {
        // 用户名下最多存在三条未关闭工单，请及时关闭处理完毕的工单以便您提交新工单
        LambdaQueryWrapper<CnWorkOrder> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(CnWorkOrder::getCreateBy, SecurityUtils.getUserId().toString());
        queryWrapper.eq(CnWorkOrder::getStatus, WorkOrderStatusEnum.IN_PROGRESS);
        long count = count(queryWrapper);
        if (count >= 3) {
            throw new ServiceException("最多存在三条未关闭工单，请及时关闭处理完毕的工单以便您提交新工单!");
        }
        // 生成工单号
        cnWorkOrder.setOrderNum("TS" + SnowFlakeUtil.getSnowFlakeId());
        cnWorkOrder.setStatus(WorkOrderStatusEnum.IN_PROGRESS);
        cnWorkOrder.setCreateBy(SecurityUtils.getUserId().toString());
        // 将工单信息保存至工单留言中
        boolean save = save(cnWorkOrder);
        if (save){
            CnWorkOrderDetail orderDetail = new CnWorkOrderDetail();
            orderDetail.setOrderNum(cnWorkOrder.getOrderNum());
            orderDetail.setReadStatus(false);
            orderDetail.setUserId(SecurityUtils.getUserId());
            orderDetail.setContent(cnWorkOrder.getProblemDescription());
            orderDetail.setCreateBy(SecurityUtils.getUserId().toString());
            orderDetail.setUserType(SecurityUtils.getLoginUser().getUser().getUserType());
            orderDetail.setContentType("1");
            orderDetail.setCreateTime(new Date());
            cnWorkOrderDetailService.save(orderDetail);
        }

        return true;
    }

    /**
     * 修改工单
     *
     * @param cnWorkOrder 工单
     * @return 结果
     */
    @Override
    public boolean updateCnWorkOrder(CnWorkOrder cnWorkOrder) {
        cnWorkOrder.setUpdateBy(SecurityUtils.getUserId().toString());
        cnWorkOrder.setUpdateTime(DateUtils.getNowDate());
        if (StringUtils.isNull(cnWorkOrder.getStatus())) {
            throw new ServiceException("工单状态不能为空");
        }
        return updateById(cnWorkOrder);
    }

    /**
     * 批量删除工单
     *
     * @param orderNums 需要删除的工单主键
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteCnWorkOrderByOrderNums(List<String> orderNums) {
        // 删除工单详细表数据
        LambdaQueryWrapper<CnWorkOrderDetail> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CnWorkOrderDetail::getOrderNum, orderNums);
        queryWrapper.eq(CnWorkOrderDetail::getContentType, 2);
        List<CnWorkOrderDetail> workOrderDetails = cnWorkOrderDetailService.list(queryWrapper);
        // 本地资源路径
        String localPath = XbtsConfig.getProfile();

        List<String> filePaths = new ArrayList<>(workOrderDetails.size());
        for (CnWorkOrderDetail workOrderDetail : workOrderDetails) {
            String content = workOrderDetail.getContent();
            content = content.replaceAll(".*" + Constants.RESOURCE_PREFIX, "");
            String filePath = localPath + content;
            filePaths.add(filePath);
        }
        // 内容为附件时，删除附件
        for (String filePath : filePaths) {
            try {
                FileUtils.deleteFile(filePath);
            } catch (Exception e) {
                log.error("删除文件失败！" + e);
            }
        }
        LambdaQueryWrapper<CnWorkOrderDetail> deleteWrapper = new LambdaQueryWrapper<>();
        deleteWrapper.in(CnWorkOrderDetail::getOrderNum, orderNums);
        cnWorkOrderDetailService.remove(deleteWrapper);
        // 删除工单表数据
        return removeBatchByIds(orderNums);
    }

    /**
     * 删除工单信息
     *
     * @param orderNum 工单主键
     * @return 结果
     */
    @Transactional
    @Override
    public boolean deleteCnWorkOrderByOrderNum(String orderNum) {
        return removeById(orderNum);
    }

}
